#!/bin/bash

#Simple Tables
# (C) 2008 Elton Pereira
#
# This code is licenced under the GPL v2.
#

# O simpletables é configurado para trabalhar com policiamento RESTRITIVO, ou seja, adiciona-se regras para liberar determinado recurso e o que sobrar é bloqueado.
# Use este script por sua própria responsabilidade, qualquer dano causado pela má configuração ou bugs correntes/futuros são de sua responsabilidade. O autor apenas garante a disponibilidade a todo o código fonte que está sob a licença GPL v2.
# Atualmente este script encontra-se em desenvolvimento, portanto é extremamente desaconselhável seu uso em um ambiente de produção.

############################### Funções #######################################
# pre_start -		Verifica a existência dos arquivos de configuração.
# start_config -	Configura opções do kernel.
# start_default -	Define a configuração do policiamento padrão.
# start -		Cria as regras de liberação.
# stop -		Desliga todo sistema de firewall.
# clear -		Apaga todas as regras de todas as tabelas.
# lock_all -		Apaga todas as regras e define o policiamento padrão para bloquear tudo.
# unlock_all -		Apaga todas as regras e define o policiamento padrão para liberar tudo.

BASE_DIR=~/simpletables
HOSTS=$BASE_DIR/etc/hosts
OPEN_PORTS=$BASE_DIR/etc/open_ports
CONFIG=$BASE_DIR/etc/simpletables.conf
IFACE_NET=`grep -v \# $CONFIG | grep -i iface_net | cut -d = -f 2`

# Verifica arquivos necessários a inicialização do firewall.
pre_start(){
	test -e $HOSTS

	if [ $? = 0 ]; then
		echo "Arquivo de configuração de hosts OK!"
	else
		echo "Faltando arquivo de configuração de hosts: " $HOSTS
		exit 2
	fi

	test -e $CONFIG

	if [ $? = 0 ]; then
		echo "Arquivo de configuração do simpletables OK!"
		start_default
	else
		echo "Faltando arquivo de configuração de hosts: " $CONFIG
		exit 2
	fi

	start_config
}

# Configura opções do kernel. E variáveis que serão usadas.
start_config(){
	clear

	MASQUERADE=`grep -v \# $CONFIG | grep -i masquerade | cut -d = -f 2`
	NETWORK=`grep -v \# $CONFIG | grep -i network | cut -d = -f 2`
	
	if [ $MASQUERADE -ge 1 ]; then
		MASQUERADE=1
		iptables -t nat -A POSTROUTING -s $NETWORK -d 0/0 -o $IFACE_NET -j MASQUERADE
	else
		MASQUERADE=0
	fi

	echo $MASQUERADE > /proc/sys/net/ipv4/ip_forward
	
	N_IFACE=0
	
	for i in `grep -v \# $CONFIG | grep -i NET[0-9] | cut -d = -f 2`;
	do
		ifconfig $i 1 2> /dev/null

		if [ $? = 0 ]; then
			export NET$N_IFACE=$i
			let N_IFACE++
		else
			echo Interface $i não existe.
		fi
	done

	N_IFACE=0

	for i in `grep -v \# $CONFIG | grep WWW[0-9] | cut -d = -f 2`;
	do
		ifconfig $i 1 2> /dev/null

		if [ $? = 0 ]; then
			set WWW$N_IFACE=$i;
			let N_IFACE++
		else
			echo Interface $i não existe.
		fi
	done

	start_default
}

# Configura o policiamento padrão das tabelas.
start_default(){
	for i in  `grep -v \# $CONFIG | grep -i '[filter|nat|mangle]_policy_*'`;
	do
		a=`echo $i | cut -d = -f 1`
		case $a in
			filter_policy_input)
				iptables -t filter -P INPUT `echo $i | cut -d = -f 2`
			;;
			filter_policy_forward)
				iptables -t filter -P OUTPUT `echo $i | cut -d = -f 2`
			;;
			filter_policy_output)
				iptables -t filter -P FORWARD `echo $i | cut -d = -f 2`
			;;
			nat_policy_prerouting)
				iptables -t nat -P PREROUTING `echo $i | cut -d = -f 2`
			;;
			nat_policy_postrouting)
				iptables -t nat -P POSTROUTING `echo $i | cut -d = -f 2`
			;;
			nat_policy_output)
				iptables -t nat -P OUTPUT `echo $i | cut -d = -f 2`
			;;
			mangle_log_prefix_input)
				iptables -t mangle -P INPUT `echo $i | cut -d = -f 2`
			;;
			mangle_log_prefix_output)
				iptables -t mangle -P OUTPUT `echo $i | cut -d = -f 2`
			;;
			mangle_log_prefix_forward)
				iptables -t mangle -P FORWARD `echo $i | cut -d = -f 2`
			;;
			mangle_log_prefix_prerouting)
				iptables -t mangle -P PREROUTING `echo $i | cut -d = -f 2`
			;;
			mangle_log_prefix_postrouting)
				iptables -t mangle -P POSTROUTING `echo $i | cut -d = -f 2`
			;;
		esac
	done

	start
}

#start_protection(){
#
#}

start(){
	for i in `cat $HOSTS | grep -v \#`;
		do iptables -A INPUT -i eth0 -d $i -j ACCEPT;
	done

	start_log
}

start_log(){
	ENABLE_LOG=`grep -v \# $CONFIG | grep -i '[filter|nat|mangle]_log_enable_*' | grep '[1|on|true]' | cut -d = -f 1`
	
	for i in  `grep -v \# $CONFIG | grep -i '[filter|nat|mangle]_log_prefix_*'`;
	do
		a=`echo $i | cut -d = -f 1`
		case $a in
			filter_log_prefix_input)

			echo $ENABLE_LOG | grep -i filter_log_enable_input > /dev/null
			if [ $? = 0 ];
			then
		       		iptables -t filter -A INPUT -j LOG --log-level info --log-prefix " `echo $i | grep -i filter_log_prefix_input | cut -d = -f 2` "
			fi
			;;
			
			filter_log_prefix_forward)
			echo $ENABLE_LOG | grep -i filter_log_enable_forward > /dev/null
			if [ $? = 0 ];
			then
		       		iptables -t filter -A FORWARD -j LOG --log-level info --log-prefix " `echo $i | grep -i filter_log_prefix_forward | cut -d = -f 2` "
			fi
			;;
			
			filter_log_prefix_output)
			echo $ENABLE_LOG | grep -i filter_log_enable_output > /dev/null
			if [ $? = 0 ];
			then
		       		iptables -t filter -A OUTPUT -j LOG --log-level info --log-prefix " `echo $i | grep -i filter_log_prefix_output | cut -d = -f 2` "
			fi
			;;
			
			nat_log_prefix_prerouting)
			echo $ENABLE_LOG | grep -i nat_log_enable_prerouting > /dev/null
			if [ $? = 0 ];
			then
			       	iptables -t nat -A PREROUTING -j LOG --log-level info --log-prefix " `echo $i | grep -i nat_log_prefix_prerouting | cut -d = -f 2` "
			fi
			;;
			
			nat_log_prefix_postrouting)
			echo $ENABLE_LOG | grep -i nat_log_enable_postrouting > /dev/null
			if [ $? = 0 ];
			then
			       	iptables -t nat -A POSTROUTING -j LOG --log-level info --log-prefix " `echo $i | grep -i nat_log_prefix_postrouting | cut -d = -f 2` "
			fi
			;;
			
			nat_log_prefix_output)
			echo $ENABLE_LOG | grep -i nat_log_enable_output > /dev/null
			if [ $? = 0 ];
			then
		       		iptables -t nat -A OUTPUT -j LOG --log-level info --log-prefix " `echo $i | grep -i nat_log_prefix_output | cut -d = -f 2` "
			fi
			;;
			
			mangle_log_prefix_prerouting)
			echo $ENABLE_LOG | grep -i mangle_log_enable_prerouting > /dev/null
			if [ $? = 0 ];
			then
		  	     	iptables -t mangle -A PREROUTING -j LOG --log-level info --log-prefix " `echo $i | grep -i mangle_log_prefix_prerouting | cut -d = -f 2` "
			fi
			;;
			
			mangle_log_prefix_postrouting)
			echo $ENABLE_LOG | grep -i mangle_log_enable_postrouting > /dev/null
			if [ $? = 0 ];
			then
		       		iptables -t mangle -A POSTROUTING -j LOG --log-level info --log-prefix " `echo $i | grep -i mangle_log_prefix_postrouting | cut -d = -f 2` "
			fi
			;;
			
			mangle_log_prefix_input)
			echo $ENABLE_LOG | grep -i mangle_log_enable_input > /dev/null
			if [ $? = 0 ];
			then
			       	iptables -t mangle -A INPUT -j LOG --log-level info --log-prefix " `echo $i | grep -i mangle_log_prefix_input | cut -d = -f 2` "
			fi
			;;
			
			mangle_log_prefix_output)
			echo $ENABLE_LOG | grep -i mangle_log_enable_output > /dev/null
			if [ $? = 0 ];
			then
			       	iptables -t mangle -A OUTPUT -j LOG --log-level info --log-prefix " `echo $i | grep -i mangle_log_prefix_output | cut -d = -f 2` "
			fi
			;;
			
			mangle_log_prefix_forward)
			echo $ENABLE_LOG | grep -i mangle_log_enable_forward > /dev/null
			if [ $? = 0 ];
			then
			       	iptables -t mangle -A FORWARD -j LOG --log-level info --log-prefix " `echo $i | grep -i mangle_log_prefix_forward | cut -d = -f 2` "
			fi
			;;
		esac
	done
}

# Bloqueio geral.
lock_all(){
	clear
	echo "ATENÇÃO! TODAS CONEXÕES FORAM BLOQUEADAS!"
	iptables -P INPUT DROP
	iptables -P OUTPUT DROP
	iptables -P FORWARD DROP
}

# Desliga o firewall
stop(){
	echo Apagando regras...
	clear
	unlock_all
}

# Apaga todas as regras das tabelas
clear(){
	iptables -t filter -F
	iptables -t nat -F
	iptables -t mangle -F
}

unlock_all(){
	# filter
	iptables -t filter -P INPUT ACCEPT
	iptables -t filter -P OUTPUT ACCEPT
	iptables -t filter -P FORWARD ACCEPT
	# nat
	iptables -t nat -P POSTROUTING ACCEPT
	iptables -t nat -P PREROUTING ACCEPT
	iptables -t nat -P OUTPUT ACCEPT
	# mangle
	iptables -t mangle -P PREROUTING ACCEPT
	iptables -t mangle -P OUTPUT ACCEPT
}

case "$1" in
	"start")
	pre_start
;;
	"stop")
	stop
;;
	"lock")
	lock_all
;;
	*)
	echo "Use os parâmetros start ou stop ou lock"
esac

